#pragma once

#include <vector>
#include <sys/epoll.h>
#include <memory>
#include <Channel.h>
#include <map>
#include <iostream>
#include <cstring>
#include <cassert>

class EventLoop;

class Epoller
{
    friend class ChatServer;
    using ChannelMap = std::map<int, Channel *>;

public:
    Epoller(EventLoop *loop, int epollFlag = EPOLL_CLOEXEC);

    int poll(int timeoutMs, std::vector<Channel *>& activeChannels);

    void updateChannel(Channel *channel);

    bool hasChannel(Channel *channel);

    void removeChannel(Channel *channel);

private:
    void fillActiveChannels(int numEvents, std::vector<Channel *> &activeChannels);

    /// @brief 增删改channel中的fd和event到epollfd中
    /// @param operation 操作类型
    /// @param channel 被操作的channel
    /// @return
    bool update(int operation, Channel *channel);

private:
    int epollfd_;
    EventLoop *ownerLoop_;
    ChannelMap channelMap_;
    std::vector<epoll_event> events_;
};
